package com.autodesk.akn.emr.web.controller;

import com.autodesk.akn.emr.dao.S3DaoImpl;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.logging.Logger;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;


public class S3Controller extends MultiActionController {
    
    private final static Logger LOGGER = Logger.getLogger(S3Controller.class.getName());
    
    private S3DaoImpl s3DAO;
    
    public S3DaoImpl getS3DAO() {
        return s3DAO;
    }

    public void setS3DAO(S3DaoImpl s3DAO) {
        this.s3DAO = s3DAO;
    }

    @RequestMapping(value = "s3/list", method = RequestMethod.GET)
    public ModelAndView list(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {
        ModelAndView model = new ModelAndView("s3/listbuckets");
        model.addObject("s3List", s3DAO.listBuckets());
        return model;
    }
    
    @RequestMapping(value = "s3/getBucket", method = RequestMethod.GET)
    public ModelAndView getBucket(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {
        ModelAndView model = new ModelAndView("s3/listbuckets");
        String bucketName = hsr.getParameter("bucket");
        String prefix = hsr.getParameter("prefix");
        model.addObject("bucketContent",s3DAO.listObjects(bucketName,prefix,"/"));
        model.addObject("s3List", s3DAO.listBuckets());
        return model;
    }

    @RequestMapping(value = "s3/createBucket", method = RequestMethod.POST)
    public ModelAndView createBucket(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {
        ModelAndView model = new ModelAndView("s3/listbuckets");
        String bucketName = hsr.getParameter("add-bucket-name");
        if(bucketName!=null && !bucketName.isEmpty()){
            s3DAO.createBucket(bucketName,"us-west-1");
        }
        model.addObject("s3List", s3DAO.listBuckets());
        return model;
    }

    @RequestMapping(value = "s3/deleteBucket", method = RequestMethod.POST)
    public ModelAndView deleteBucket(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {
        ModelAndView model = new ModelAndView("s3/listbuckets");
        String bucketName = hsr.getParameter("delete-bucket-name");
        if(bucketName!=null && !bucketName.isEmpty()){
            s3DAO.deleteBucket(bucketName);
        }
        model.addObject("s3List", s3DAO.listBuckets());
        return model;
    }
    
        @RequestMapping(value = "s3/deleteObject", method = RequestMethod.POST)
    public ModelAndView deleteObject(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {
        String objectName = hsr.getParameter("objectName");
        String bucketName = hsr.getParameter("bucketName");
        if(bucketName!=null && !bucketName.isEmpty() && objectName!=null && !objectName.isEmpty()){
            s3DAO.deleteObject(bucketName,objectName);
        }
        return null;
    }

    @RequestMapping(value = "s3/downloadObject", method = RequestMethod.GET)
    public ModelAndView downloadObject(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {
        String bucketName = hsr.getParameter("bucketName");
        String objectName = hsr.getParameter("objectName");
        if(bucketName!=null && objectName!=null){
            hsr1.setContentType("application/octet-stream");
            String [] headerFileName = objectName.split("/");
            hsr1.setHeader("Content-Disposition", "attachment; filename="+headerFileName[(headerFileName.length-1)]);
            int retValue = s3DAO.getObject(bucketName, objectName, hsr1.getOutputStream());
            LOGGER.info("Download Object Action Result: " + retValue);
            if(retValue == -1){
                hsr1.sendError(404,"The file cannot be downloaded");
            }
        }
        return null;
    }
    
    @RequestMapping(value = "s3/upload.do", method = RequestMethod.POST)
    public ModelAndView upload(HttpServletRequest hsr, HttpServletResponse hsr1)
            throws Exception {

        ServletFileUpload upload = new ServletFileUpload();        
        FileItemIterator iterator = upload.getItemIterator(hsr);
        String type;        
        String bucketName = "";
        String filePath = "";
        String fileName;
        String fullParameter ;
        while (iterator.hasNext()) {
            FileItemStream item = iterator.next();
            if (item.isFormField()) {
                if(item.getFieldName()!=null && item.getFieldName().startsWith("bucketPath:")){                    
                    fullParameter = item.getFieldName();
                    String []fullParameterSlip=fullParameter.split(":");
                    String []bucketSlip=fullParameterSlip[1].split("/");
                    bucketName=bucketSlip[0];
                    filePath= (bucketSlip.length > 1) ?  fullParameterSlip[1].replace(bucketName+"/", "") : "";                
                }
            } else {
                type = item.getContentType();
                fileName = item.getName();
                filePath= (filePath.equals("")) ?  fileName : filePath+fileName;                
                LOGGER.info("bucket: "+bucketName+ "| filePath:" + filePath + "| fileName:" + fileName + "| type:" + type);
                s3DAO.putObject(item.openStream(),type,bucketName,filePath);
            }
        }
        ModelAndView model = new ModelAndView("s3/listbuckets");
        model.addObject("s3List", s3DAO.listBuckets());
        return model;
    }
}
